﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Semantics.IR
{
    public class Transformer
    {
        Graph Ontology;
        List<GraphGrammarRule> Rules = new List<GraphGrammarRule>();
        public Transformer(Graph ontology)
        {
            this.Ontology = ontology;
            this.SetupRules();
        }
        public void Transform(Graph graph)
        {
            IEnumerator enumerator = graph.edgesHash.GetEnumerator();
            while (enumerator.MoveNext())
            {
                Edge edge = (Edge)((DictionaryEntry)enumerator.Current).Value;
                Transform(graph, edge);
            }
        }
        void SetupRules()
        {
            string[,,] ruletexts =
            {
                {{"[人]","是","[事物]"},{"[人]","姓名","[事物]"}, {"False", "True","False"}},
            };
            for (int i = 0; i < ruletexts.GetLength(0); i++)
            {
                GraphGrammarRule rule = new GraphGrammarRule();
                Node outgoing2 = this.Ontology.ResolveNode(ruletexts[0, 1, 0]);
                Node type2 = this.Ontology.ResolveNode(ruletexts[0, 1, 1]);
                Node incoming2 = this.Ontology.ResolveNode(ruletexts[0, 1, 2]);
                Node outgoing = this.Ontology.ResolveNode(ruletexts[0, 0, 0]);
                Node type = this.Ontology.ResolveNode(ruletexts[0, 0, 1]);
                Node incoming = this.Ontology.ResolveNode(ruletexts[0, 0, 2]);

                rule.Original = new Edge(type, outgoing, incoming);
                rule.Transofmed = new Edge(type2, outgoing2, incoming2);
                rule.ReplaceOutgoing = Convert.ToBoolean(ruletexts[0, 2, 0]);
                rule.ReplaceEdgeType = Convert.ToBoolean(ruletexts[0, 2, 1]);
                rule.ReplateIncoming = Convert.ToBoolean(ruletexts[0, 2, 2]);
                this.Rules.Add(rule);
            }
        }
        void Transform(Graph graph, Edge edge)
        {
            for(int i=0;i<Rules.Count;i++)
            {
                GraphGrammarRule rule=Rules[i];
                if (Match(edge, rule.Original))
                {
                    if (rule.ReplaceEdgeType)
                    {
                        edge.Class = GraphUtility.ResolveOrCreate(graph, rule.Transofmed.Class);
                        if (edge.Class.Class == null)
                            edge.Class.Class = rule.Transofmed.Class;
                    }
                }
            }
        }

        bool Match(Edge edge, Edge template)
        {
            if (!edge.Incoming.Class.Is(template.Incoming))
                return false;
            if (!edge.Outgoing.Class.Is(template.Outgoing))
                return false;
            if (!edge.Class.Class.Is(template.Class))
                return false;
            return true;
        }
        class GraphGrammarRule
        {
            public Edge Original;
            public Edge Transofmed;
            public bool ReplaceOutgoing;
            public bool ReplaceEdgeType;
            public bool ReplateIncoming;
        }

    }
}
